package com.ds.iecs.im.store;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.stream.Collectors;

import org.mx.DigestUtils;
import org.mx.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import lombok.Getter;
import lombok.Setter;

/**
 * 聊天室
 * 
 * @author john.peng
 *
 */
@Component("meetingRoomManager")
public class MeetingRoomManager {
	private static final Logger logger = LoggerFactory.getLogger(MeetingRoomManager.class);

	private Map<String, MeetingRoom> meetingRooms;

	/**
	 * 构造函数
	 */
	public MeetingRoomManager() {
		super();
		meetingRooms = new HashMap<String, MeetingRoomManager.MeetingRoom>();
	}

	/**
	 * 创建一个聊天室
	 * 
	 * @param name 名称
	 * @return 聊天室
	 */
	public MeetingRoom createMeetingRoom(String name) {
		return createMeetingRoom(name, null, null);
	}

	/**
	 * 创建一个聊天室
	 * 
	 * @param name 名称
	 * @param desc 描述
	 * @return 聊天室
	 */
	public MeetingRoom createMeetingRoom(String name, String desc) {
		return createMeetingRoom(name, desc, null);
	}

	/**
	 * 创建一个聊天室
	 * 
	 * @param name    名称
	 * @param desc    描述
	 * @param manager 管理员
	 * @return 聊天室
	 */
	public MeetingRoom createMeetingRoom(String name, String desc, String manager) {
		return createMeetingRoom(name, desc, manager);
	}

	/**
	 * 创建一个聊天室
	 * 
	 * @param name    名称
	 * @param desc    描述
	 * @param manager 管理员
	 * @param members 成员列表
	 * @return 聊天室
	 */
	public MeetingRoom createMeetingRoom(String name, String desc, String manager, String... members) {
		MeetingRoom room = new MeetingRoom();
		room.setName(name);
		room.setDesc(desc);
		room.setManager(manager);
		Set<String> set = new HashSet<String>();
		for (String user : members) {
			set.add(user);
		}
		room.setMembers(set);
		meetingRooms.put(name, room);
		if (logger.isDebugEnabled()) {
			logger.debug(String.format("Create a new meeting room['%s'] success.", name));
		}
		return room;
	}

	/**
	 * 获取指定用户所管理的聊天室列表
	 * 
	 * @param userId 用户ID
	 * @return 聊天室列表
	 */
	public Collection<MeetingRoom> getManagedMeetingRooms(String userId) {
		return meetingRooms.values().stream().filter(room -> userId.equals(room.getManager()))
				.collect(Collectors.toList());
	}

	/**
	 * 获取指定用户所属的聊天室列表，可能是管理者或者聊天成员。
	 * 
	 * @param userId 用户ID
	 * @return 聊天室列表
	 */
	public Collection<MeetingRoom> getMeetingRooms(String userId) {
		return meetingRooms.values().stream()
				.filter(room -> userId.equals(room.getManager()) || room.getMembers().contains(userId))
				.collect(Collectors.toList());
	}

	/**
	 * 获取指定的聊天室
	 * 
	 * @param name 聊天室名称
	 * @return 聊天室
	 */
	public MeetingRoom getMeetingRoom(String name) {
		return meetingRooms.get(name);
	}

	/**
	 * 获取所有有效的聊天室
	 * 
	 * @return 聊天室列表
	 */
	public Collection<MeetingRoom> getMeetingRooms() {
		return meetingRooms.values();
	}

	/**
	 * 聊天室
	 * 
	 * @author john.peng
	 *
	 */
	public class MeetingRoom {
		/**
		 * 名称
		 */
		@Getter
		@Setter
		private String name;
		/**
		 * 描述
		 */
		@Getter
		@Setter
		private String desc;
		/**
		 * 管理员
		 */
		@Getter
		@Setter
		private String manager;
		/**
		 * 创建时间
		 */
		@Getter
		private long createdTime = System.currentTimeMillis();
		/**
		 * 成员
		 */
		@Getter
		@Setter
		private Set<String> members;

		private Queue<Message> cachedMessages = new LinkedList<MeetingRoomManager.Message>();

		/**
		 * 最大缓存数量
		 */
		@Getter
		@Setter
		private int maxCachedSize = 500;

		/**
		 * 缓存一条消息
		 * 
		 * @param content  消息内容
		 * @param userId   发送用户
		 * @param sentTime 发送时间
		 * @param priority 优先级
		 * @return 被缓存的消息
		 */
		public Message cache(String content, String userId, long sentTime, int priority) {
			while (cachedMessages.size() >= maxCachedSize) {
				cachedMessages.poll();
			}
			Message message = new Message(content, userId, sentTime, priority);
			cachedMessages.add(message);
			return message;
		}

		/**
		 * 获取指定用户发送的缓存消息
		 * 
		 * @param userId 用户ID
		 * @return 消息集合
		 */
		public Collection<Message> getCachedMessages(String userId) {
			return cachedMessages.parallelStream().filter(message -> message.getUserId().equals(userId))
					.collect(Collectors.toList());
		}

		/**
		 * 获取缓存的消息
		 * 
		 * @return 消息集合
		 */
		public Collection<Message> getCachedMessages() {
			return cachedMessages.parallelStream().collect(Collectors.toList());
		}

		/**
		 * 获取当前缓存消息的数量
		 * 
		 * @return 数量
		 */
		public int getCahcedMessageSize() {
			return cachedMessages.size();
		}

		/**
		 * 获取聊天室成员数量
		 * 
		 * @return 数量
		 */
		public int getMemeberSize() {
			return members == null ? 0 : members.size();
		}
	}

	/**
	 * 聊天室消息
	 * 
	 * @author john.peng
	 *
	 */
	@Getter
	public class Message {
		/**
		 * 消息ID
		 */
		private String id;
		/**
		 * 消息内容
		 */
		private String content;
		/**
		 * 发送用户
		 */
		private String userId;
		/**
		 * 发送时间
		 */
		private long sentTime;
		/**
		 * 优先级
		 */
		private int priority;

		/**
		 * 构造函数
		 * 
		 * @param content  消息内容
		 * @param userId   发送用户
		 * @param sentTime 发送时间
		 * @param priority 优先级
		 */
		public Message(String content, String userId, long sentTime, int priority) {
			this(null, content, userId, sentTime, priority);
		}

		/**
		 * 构造函数
		 * 
		 * @param id       消息ID
		 * @param content  消息内容
		 * @param userId   发送用户
		 * @param sentTime 发送时间
		 * @param priority 优先级
		 */
		public Message(String id, String content, String userId, long sentTime, int priority) {
			super();
			if (StringUtils.isBlank(id)) {
				id = DigestUtils.uuid();
			}
			this.id = id;
			this.content = content;
			this.userId = userId;
			this.sentTime = sentTime;
			this.priority = priority;
		}
	}
}
